/*
 * @Author: xiaosihan
 * @Date: 2025-01-15 21:02:27
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2025-01-15 22:22:22
 */

import {
    Color,
    DoubleSide,
    ShaderChunk,
    ShaderMaterial,
    Vector2
} from "three";
import threeUtils from "three-base/threeUtils";

// 假设typeState已经被定义
const typeState = {
  color: "#0670c1",
  speed: 0.1,
  brightness: 1.5,
  flowSpeed: { x: 0.01, y: 0.01 },
};

let vertexShader = `// Examples of variables passed from vertex to fragment shader
    ${ShaderChunk.common}
    ${ShaderChunk.logdepthbuf_pars_vertex}
    varying vec2 vUv;

    void main(){
        // To pass variables to the fragment shader, you assign them here in the
        // main function. Traditionally you name the varying with vAttributeName
        vUv=uv;
        
        // This sets the position of the vertex in 3d space. The correct math is
        // provided below to take into account camera and object data.
        gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);
        ${ShaderChunk.logdepthbuf_vertex}
    }`;
let fragmentShader = `
    ${ShaderChunk.logdepthbuf_pars_fragment}
    #define TAU 6.28318530718
    #define MAX_ITER 5

    uniform vec2 resolution;
    uniform vec3 backgroundColor;
    uniform vec3 color;
    uniform float speed;
    uniform vec2 flowSpeed;
    uniform float brightness;
    uniform float time;

    varying vec2 vUv;

    void main(){
        vec2 uv=(vUv.xy+(time*flowSpeed))*resolution;
        
        vec2 p=mod(uv*TAU,TAU)-250.;
        vec2 i=vec2(p);
        
        float c=1.;
        float inten=.005;
        
        for(int n=0;n<MAX_ITER;n++){
            float t=time*speed*(1.-(3.5/float(n+1)));
            i=p+vec2(cos(t-i.x)+sin(t+i.y),sin(t-i.y)+cos(t+i.x));
            c+=1./length(vec2(p.x/(sin(i.x+t)/inten),p.y/(cos(i.y+t)/inten)));
        }
        
        c/=float(MAX_ITER);
        c=1.17-pow(c,brightness);
        
        vec3 rgb=vec3(pow(abs(c),8.));
        
        gl_FragColor=vec4(rgb*color+backgroundColor,length(rgb)+.1);
        ${ShaderChunk.logdepthbuf_fragment}
    }`;

// 特效材质1
const effectMaterial1 = new ShaderMaterial({
  uniforms: {
    resolution: { value: new Vector2(1, 1) },
    backgroundColor: { value: new Color("#0670c1") },
    color: { value: new Color("#fff") },
    speed: { value: 0.1 },
    flowSpeed: { value: new Vector2(0.01, 0.01) },
    brightness: { value: 1.5 },
    time: { value: 0.1 },
  },
  vertexShader: vertexShader,
  fragmentShader: fragmentShader,
  side: DoubleSide,
  transparent: true,
  depthWrite: true,
  depthTest: true,
});

threeUtils.addEventListener("requestAnimationFrame", ({ timeTemp }: any) => {
  effectMaterial1.uniforms.time.value = timeTemp / 100;
});

export default effectMaterial1;
